package com.xky.ui.module.login;

import com.xky.pojo.User;
import com.xky.ui.main.MainView;
import com.xky.ui.module.register.Register;
import com.xky.utils.DBUtils;
import javax.swing.*;
import java.awt.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 总结：
 * 制作该界面总共分6个部分
 * 1、登录界面类：主要制作主窗口以容纳其他组件
 * 2、初始化界面组件：主要对主界面进行美化，包括主面板（带自适应背景）、添加图标背景、标题的设置、中央表单面板的设置、底部按钮面板的设置
 * 3、 创建表单面板：包括用户名和密码的提示词及输入框
 * 4、创建按钮面板：创建登录按钮盒注册按钮及点击事件和按钮的美化
 * 5、登录事件：设置当点击登录按钮后有怎样的时间，及验证用户名和密码，与mysql数据库连接验证用户名和密码的正确性，如果用户把密码输错后，系统会提示
 * 输入错误并清空密码输入框
 * 6、启动：启动主窗口
 */
// 登录界面类，继承自 JFrame
public class Login extends JFrame {
    private JTextField usernameField; // 用户名输入框
    private JPasswordField passwordField; // 密码输入框

    // 构造函数，初始化登录界面
    public Login() {
        setTitle("登录界面"); // 设置窗口标题
        setSize(450, 450); // 设置窗口大小
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭操作
        setLocationRelativeTo(null); // 窗口居中显示
        init(); // 初始化界面组件
        setVisible(true); // 显示窗口
    }

    // 初始化界面组件
    public void init() {
        // 主面板
        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.setBackground(new Color(255, 182, 193));

        setContentPane(mainPanel);

        // 标题（顶部）
        JLabel titleLabel = new JLabel("用户登录", SwingConstants.CENTER); // 创建标题标签
        titleLabel.setFont(new Font("华文行楷", Font.PLAIN, 40)); // 设置字体
        titleLabel.setOpaque(false); // 设置标签为透明
        mainPanel.add(titleLabel, BorderLayout.NORTH); // 将标签添加到主面板的北部

        // 中央表单面板
        JPanel formPanel = createFormPanel(); // 创建表单面板
        mainPanel.add(formPanel, BorderLayout.CENTER); // 将表单面板添加到主面板的中央

        // 底部按钮面板
        JPanel buttonPanel = createButtonPanel(); // 创建按钮面板
        mainPanel.add(buttonPanel, BorderLayout.SOUTH); // 将按钮面板添加到主面板的南部
    }

    // 创建表单面板
    private JPanel createFormPanel() {
        JPanel formPanel = new JPanel(new GridBagLayout()); // 创建表单面板，使用 GridBagLayout 布局
        formPanel.setOpaque(false); // 设置面板为透明
        GridBagConstraints gbc = new GridBagConstraints(); // 创建布局约束
        gbc.insets = new Insets(7, 0, 7, 0); // 设置组件之间的间距
        Font font = new Font("微软雅黑", Font.PLAIN, 20);

        // 用户名标签
        JLabel usernameLabel = new JLabel("用户名：");
        usernameLabel.setFont(font);
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(10,50,10,10);
        gbc.weightx = 0.0;
        gbc.fill = GridBagConstraints.NONE;
        formPanel.add(usernameLabel, gbc);

        // 用户名输入框
        usernameField = new JTextField(20);
        usernameField.setPreferredSize(new Dimension(250,35));
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.weightx = 1.0; // 让输入框占用所有可用的水平空间
        gbc.insets = new Insets(10,0,10,50);
        gbc.fill = GridBagConstraints.HORIZONTAL;
        formPanel.add(usernameField, gbc);

        // 密码标签
        JLabel passwordLabel = new JLabel("密码：");
        passwordLabel.setFont(font);
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.weightx = 0.0;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(10,50,10,10);
        gbc.fill = GridBagConstraints.NONE;
        formPanel.add(passwordLabel, gbc);

        // 密码输入框
        passwordField = new JPasswordField(20);
        passwordField.setPreferredSize(new Dimension(250,35));
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.gridwidth = 2;
        gbc.insets = new Insets(10,0,10,50);
        gbc.fill = GridBagConstraints.HORIZONTAL;
        formPanel.add(passwordField, gbc);

        //角色提示
        JLabel jLabel = new JLabel("你当前登录的角色是管理员");
        jLabel.setFont(new Font("华文行楷",Font.PLAIN,15));
        jLabel.setForeground(Color.BLACK);
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.insets = new Insets(5,30,10,10);
        formPanel.add(jLabel,gbc);

        return formPanel; // 返回表单面板
    }

    // 创建按钮面板
    private JPanel createButtonPanel() {
        JPanel buttonPanel = new JPanel(new GridBagLayout()); // 创建按钮面板，使用 GridBagLayout 布局
        buttonPanel.setOpaque(false); // 设置面板为透明
        GridBagConstraints gbc = new GridBagConstraints(); // 创建布局约束
        gbc.insets = new Insets(20, 10, 20, 10); // 设置组件之间的间距
        gbc.anchor = GridBagConstraints.CENTER; // 设置组件对齐方式

        // 登录按钮
        JButton loginButton = new JButton("登录"); // 创建登录按钮
        loginButton.setPreferredSize(new Dimension(80,35));
        loginButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
        loginButton.setBackground(Color.cyan);
        loginButton.setBorderPainted(false);
        gbc.insets = new Insets(10,10,30,10);
        loginButton.addActionListener(e1 -> {
            try {
                handleLogin(); // 处理登录事件
            } catch (SQLException e) {
                throw new RuntimeException(e); // 抛出运行时异常
            }
        });

        // 密码框回车触发登录
        passwordField.addActionListener(_ -> loginButton.doClick()); // 密码框回车时触发登录按钮点击事件

        gbc.gridx = 0; // 设置网格 x 坐标
        gbc.gridy = 0; // 设置网格 y 坐标
        buttonPanel.add(loginButton, gbc); // 将登录按钮添加到按钮面板

        // 注册按钮
        JButton registerButton = new JButton("注册"); // 创建注册按钮
        registerButton.setPreferredSize(new Dimension(80,35));
        registerButton.setBackground(Color.orange);
        registerButton.setBorderPainted(false);
        gbc.insets = new Insets(10,50,30,10);
        registerButton.addActionListener(e -> {
            dispose();
            new Register();
        });

        gbc.gridx = 1; // 设置网格 x 坐标
        buttonPanel.add(registerButton, gbc); // 将注册按钮添加到按钮面板

        return buttonPanel; // 返回按钮面板
    }

    // 处理登录事件
    private void handleLogin() throws SQLException {
        String username = usernameField.getText().trim(); // 获取用户名并去除空格
        String password = new String(passwordField.getPassword()).trim(); // 获取密码并去除空格

        if (username.isEmpty() || password.isEmpty()) {
            showError("用户名和密码不能为空"); // 如果用户名或密码为空，显示错误提示
        } else {
            User user = authenticate(username, password);
            if (user != null) {
                JOptionPane.showMessageDialog(this, "登录成功！", "成功", JOptionPane.INFORMATION_MESSAGE); // 登录成功提示
                this.dispose(); // 关闭登录窗口
                new MainView();
            } else {
                showError("用户名或密码错误"); // 用户名或密码错误提示
            }
        }
    }

    // 验证用户名和密码
    private User authenticate(String username, String password) throws SQLException {
        Connection connection = null; // 数据库连接
        PreparedStatement preparedStatement = null; // 预编译语句
        ResultSet resultSet = null; // 结果集

        try {
            connection = DBUtils.getConnection(); // 获取数据库连接
            preparedStatement = connection.prepareStatement("select * from login where username=? and password=?"); // 准备 SQL 查询
            preparedStatement.setString(1, username); // 设置用户名参数
            preparedStatement.setString(2, password); // 设置密码参数
            resultSet = preparedStatement.executeQuery(); // 执行查询

            if (resultSet.next()) {
                User user = new User();
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
                user.setEmail(resultSet.getString("email"));
                return user;
            }
            return null;
        } finally {
            DBUtils.closeAll(connection, preparedStatement, resultSet); // 关闭所有资源
        }
    }

    // 显示错误提示
    private void showError(String message) {
        JOptionPane.showMessageDialog(this, message, "错误", JOptionPane.ERROR_MESSAGE); // 显示错误提示框
        passwordField.setText(""); // 清空密码框
        passwordField.requestFocus(); // 将焦点设置到密码框
    }

    // 主方法，启动登录界面
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // 设置外观为系统外观
        } catch (Exception e) {
            e.printStackTrace(); // 打印异常堆栈
        }
        SwingUtilities.invokeLater(Login::new); // 在事件调度线程中创建登录界面
    }
}